/* eslint-disable @typescript-eslint/no-explicit-any */
import type { BrowserOptions } from '@sentry/browser';

// This is not great, but kinda necessary to make it work with Vue@2 and Vue@3 at the same time.
export interface Vue {
  config: {
    errorHandler?: any;
    warnHandler?: any;
    silent?: boolean;
  };
  mixin: (mixins: Partial<Record<Hook, any>>) => void;
}

export type ViewModel = {
  _isVue?: boolean;
  __isVue?: boolean;
  $root: ViewModel;
  $parent?: ViewModel;
  $props: { [key: string]: any };
  $options?: {
    name?: string;
    propsData?: { [key: string]: any };
    _componentTag?: string;
    __file?: string;
    __name?: string;
  };
};

export interface VueOptions {
  /** Vue constructor to be used inside the integration (as imported by `import Vue from 'vue'` in Vue2) */
  Vue?: Vue;

  /**
   * Vue app instance(s) to be used inside the integration (as generated by `createApp` in Vue3).
   */
  app?: Vue | Vue[];

  /**
   * When set to `false`, Sentry will suppress reporting of all props data
   * from your Vue components for privacy concerns.
   */
  attachProps: boolean;

  /**
   *  By default, Sentry attaches an error handler to capture exceptions and report them to Sentry.
   *  When `attachErrorHandler` is set to `false`, automatic error reporting is disabled.
   *
   *  Usually, this option should stay enabled, unless you want to set up Sentry error reporting yourself.
   *  For example, the Sentry Nuxt SDK does not attach an error handler as it's using the error hooks provided by Nuxt.
   *
   *  @default true
   */
  attachErrorHandler: boolean;

  /** {@link TracingOptions} */
  tracingOptions?: Partial<TracingOptions>;
}

export type Options = BrowserOptions & VueOptions;

/** Vue specific configuration for Tracing Integration  */
export interface TracingOptions {
  /**
   * Decides whether to track components by hooking into its lifecycle methods.
   * Can be either set to `boolean` to enable/disable tracking for all of them.
   * Or to an array of specific component names (case-sensitive).
   */
  trackComponents: boolean | string[];

  /** How long to wait until the tracked root activity is marked as finished and sent of to Sentry */
  timeout: number;

  /**
   * List of hooks to keep track of during component lifecycle.
   * Available hooks: 'activate' | 'create' | 'destroy' | 'mount' | 'unmount' | 'update'
   * Based on https://vuejs.org/v2/api/#Options-Lifecycle-Hooks
   */
  hooks: Operation[];
}

export type Hook =
  | 'activated'
  | 'beforeCreate'
  | 'beforeDestroy'
  | 'beforeUnmount'
  | 'beforeMount'
  | 'beforeUpdate'
  | 'created'
  | 'deactivated'
  | 'destroyed'
  | 'unmounted'
  | 'mounted'
  | 'updated';

export type Operation = 'activate' | 'create' | 'destroy' | 'mount' | 'update' | 'unmount';
